using System;
using System.Drawing;
using System.IO;
using System.Reflection;
using System.Xml;

namespace Pegasus.Resources
{
	/// <summary>
	/// This class is used to access embedded resouces that are in the assembly.  To add a file to the assembly as an embedded resource
	/// select the file properties and set the Build Action property to "Embedded Resource".
	/// </summary>
	public class EmbeddedResource
	{
		// Local Instance Values
		private Assembly m_assembly;
		private string m_namespace;

		// Local Const Values
		private const string RESOURCE_FORMAT = "{0}.{1}";

		/// <summary>
		/// Default Constructor.  
		/// </summary>
		/// <param name="resourceAssembly">The assembly that holds the resources.</param>
		/// <param name="Namespace">The default namespace where the resouces are at.</param>
		public EmbeddedResource( Assembly resourceAssembly, string Namespace )
		{
			m_assembly = resourceAssembly;
			m_namespace = Namespace;
		}

		/// <summary>
		/// The assembly namespace where the resouce files are located.
		/// </summary>
		public string Namespace
		{
			get
			{
				return m_namespace;
			}

			set
			{
				m_namespace = value;
			}
		}

		/// <summary>
		/// Gets the contents of a text file.
		/// </summary>
		/// <param name="filename">The filename of the resource.</param>
		/// <returns>The full content of the text file or null if the resource can not be found..</returns>
		public string GetText( string filename )
		{
			string text = null;

			string resouceName = string.Format( RESOURCE_FORMAT, m_namespace, filename );
			
			Stream resStream = m_assembly.GetManifestResourceStream( resouceName );
			if( resStream != null )
			{
				using( StreamReader textStream = new StreamReader( resStream ) )
				{
					text = textStream.ReadToEnd();
				}
			}

			return text;
		}

		/// <summary>
		/// Gets the icon file.
		/// </summary>
		/// <param name="filename">The filename of the resource.</param>
		/// <returns>The icon object or null if the resource can not be found.</returns>
		public Icon GetIcon( string filename )
		{
			Icon icon = null;

			string resouceName = string.Format( RESOURCE_FORMAT, m_namespace, filename );
			using( Stream resStream = m_assembly.GetManifestResourceStream( resouceName ) )
			{
				if( resStream != null )
				{
					icon = new Icon( resStream );
				}
			}

			return icon;
		}

		/// <summary>
		/// Gets the given bitmap file.
		/// </summary>
		/// <param name="filename">The filename of the resource.</param>
		/// <returns>The bitmap object or null if the resource can not be found.</returns>
		public Bitmap GetBitmap( string filename )
		{
			Bitmap bitmap = null;

			string resouceName = string.Format( RESOURCE_FORMAT, m_namespace, filename );

			Stream resStream = m_assembly.GetManifestResourceStream( resouceName );
			try
			{
				// WARNING: Do not close the stream for the Bitmap.  For some reason it 
				// has to remain open for the life of the bitmap.  See .NET documentation
				// the Bitmap() constructor for a stream object.
				bitmap = new Bitmap( resStream );
			}
			catch( Exception e )
			{
				// Only close the stream if we had a problem.
				resStream.Close();
				throw new Exception( "Unable to create bitmap object", e );
			}

			return bitmap;
		}

		/// <summary>
		/// Gets the XML.
		/// </summary>
		/// <param name="filename">The filename of the resource.</param>
		/// <returns>The full content of the xml file or null if the resource can not be found.</returns>
		public string GetXml( string filename )
		{
			return GetText( filename );
		}

		/// <summary>
		/// Gets an XML document object from the given xml resouce.
		/// </summary>
		/// <param name="filename">The filename of the resource.</param>
		/// <returns>The XmlDocument object or null if the resource can not be found.</returns>
		public XmlDocument GetXmlDocument( string filename )
		{
			XmlDocument xmlDoc = null;

			string resouceName = string.Format( RESOURCE_FORMAT, m_namespace, filename );
			using( Stream resStream = m_assembly.GetManifestResourceStream( resouceName ) )
			{
				if( resStream != null )
				{
					xmlDoc = new XmlDocument();
					xmlDoc.Load( resStream );
				}
			}

			return xmlDoc;
		}
	}
}
